package schemax

import (
	"gitee.com/zhongguo168a/gocodes/datax/convertx"
	"gitee.com/zhongguo168a/gocodes/datax/schemax/basickind"
)

type EnumDecl struct {
	//
	Namespace string

	Comments []string
	//
	Name string
	//
	Kind int
	//
	Fields []*Field
}

func (decl *EnumDecl) GetName() string {
	return decl.Name
}

func (decl *EnumDecl) GetNamespace() string {
	return decl.Namespace
}

func (decl *EnumDecl) GetIdent() string {
	if decl.Namespace != "" {
		return decl.Namespace + "/" + decl.Name
	}
	return decl.Name
}

func (decl *EnumDecl) RefType() string {
	return "enumdecl"
}

func (decl *EnumDecl) ValueIndex(val string) int {
	for index, field := range decl.Fields {
		if field.Value == val {
			return index
		}
	}
	return -1
}

func (decl *EnumDecl) ValueToName(ival interface{}) (r string) {
	for _, field := range decl.Fields {
		switch basickind.Kind(decl.Kind) {
		case basickind.String:
			val, ok := ival.(string)
			if ok == true {
				if field.Value == val {
					return field.Name
				}
			}
		default:
			val, ok := ival.(string)
			if ok == true {
				if field.Value == val {
					return field.Name
				}
			}
		}

	}

	return ival.(string)
}

func (decl *EnumDecl) NameIndex(name string) int {
	for index, field := range decl.Fields {
		if field.Name == name {
			return index
		}
	}
	return -1
}

func (decl *EnumDecl) NameToValueString(name string) (r string) {
	for _, field := range decl.Fields {
		if field.Name == name {
			return field.Value
		}
	}
	return
}

func (decl *EnumDecl) NameToValue(name string) (r interface{}) {
	value := decl.NameToValueString(name)
	switch basickind.Kind(decl.Kind) {
	case basickind.String:
		return value
	default:
		r = convertx.AnyToInt(value)
	}
	return
}

func (decl *EnumDecl) ConvertToValue(ival interface{}) (r interface{}) {

	lastVal := func() (x string) {
		sval := convertx.AnyToString(ival)
		vindex := decl.ValueIndex(sval)
		if vindex != -1 {
			return sval
		}
		nindex := decl.NameIndex(sval)
		if nindex != -1 {
			return decl.NameToValueString(sval)
		}

		return sval
	}()
	switch basickind.Kind(decl.Kind) {
	case basickind.Int8:
		fallthrough
	case basickind.Int16:
		fallthrough
	case basickind.Int32:
		fallthrough
	case basickind.Int64:
		if lastVal == "" {
			r = convertx.AnyToInt(ival)
		} else {
			r = convertx.AnyToInt(lastVal)
		}
	case basickind.Uint8:
		fallthrough
	case basickind.Uint16:
		fallthrough
	case basickind.Uint32:
		fallthrough
	case basickind.Uint64:
		if lastVal == "" {
			r = convertx.AnyToUint(ival)
		} else {
			r = convertx.AnyToUint(lastVal)
		}
	case basickind.String:
		return lastVal
	default:

	}

	return
}
